﻿using Autofac;
using Autofac.Core;
using System;
using System.Linq;
using System.Reflection;

namespace Silky.Core.DependencyInjection
{
    public class DefaultDependencyRegistrar : IDependencyRegistrar
    {
        public void Register(ContainerBuilder builder, ITypeFinder typeFinder)
        {
            var refAssemblies = typeFinder.GetAssemblies();
            foreach (var assembly in refAssemblies)
            {
                builder.RegisterAssemblyTypes(assembly)
                    .Where(t => typeof(ISingletonDependency).GetTypeInfo().IsAssignableFrom(t) &&
                                !t.GetCustomAttributes().OfType<InjectNamedAttribute>().Any())
                    .AsImplementedInterfaces()
                    .PropertiesAutowired()
                    .AsSelf()
                    .SingleInstance();

                builder.RegisterAssemblyTypes(assembly)
                    .Where(t => typeof(ITransientDependency).GetTypeInfo().IsAssignableFrom(t) &&
                                !t.GetCustomAttributes().OfType<InjectNamedAttribute>().Any())
                    .AsImplementedInterfaces()
                     .PropertiesAutowired()
                    .AsSelf()
                    .InstancePerDependency();

                builder.RegisterAssemblyTypes(assembly)
                    .Where(t => typeof(IScopedDependency).GetTypeInfo().IsAssignableFrom(t) &&
                                !t.GetCustomAttributes().OfType<InjectNamedAttribute>().Any())
                    .AsImplementedInterfaces()
                    .PropertiesAutowired()
                    .AsSelf()
                    .InstancePerLifetimeScope();
            }
        }

        public int Order => 1;
    }

    [AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = true)]
    public class AutowaredAttribute : Attribute
    { }

    public class PropertySelector : IPropertySelector
    {
        public bool InjectProperty(PropertyInfo propertyInfo, object instance)
        {
            return propertyInfo.CustomAttributes.Any(ca => ca.AttributeType == typeof(AutowaredAttribute));
        }
    }
}